/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package entities;

import java.awt.Graphics;
import java.awt.Image;
import java.awt.Point;
import java.util.HashMap;
import javax.swing.JPanel;
import willispace.Config;
import willispace.MapRenderer;

/**
 * Entity Class
 * @author mateusz
 */
public abstract class Entity extends MyPanel {
    /**
     * position (global)
     */
    protected volatile int x, y;
    protected boolean visable;
    protected JPanel panelContaining;
    protected Boolean isPaused;
    protected HashMap<String, String> properties;
    protected String myName;
    
    
    /**
     * current state of this entity
     */
    public States state;
    /**
     * what is entity waiting for
     */
    public WaitingStates waitFor;
    
    
    
    /**
     * Creates new entity
     * @param position          position of top-left corner from beggining of the (0,0)
     * @param defaultImage      image of entity
     * @param panelContaining   panel containing this entity
     * @param myName            name of entity
     */
    public Entity(Point position, Image defaultImage, JPanel panelContaining, String myName) {
        super(position, defaultImage);
        x = position.x;
        y = position.y;
        visable = false;
        isPaused = false;
        this.panelContaining = panelContaining;
        updateLocation();
        
        // set properties
        properties = new HashMap<String, String>();
        
        // set states
        state = States.EntityStates.NONE;
        waitFor = WaitingStates.NONE;
    
        this.myName = myName;
    }

    /**
     * Pause/unpause entity
     */
    public void pause() {
        isPaused = !isPaused;
    }
    
    /**
     * Get global coordiantes of entity
     * @return global position of entity
     */
    public Point getXY(){
        return new Point(this.x, this.y);
    }
    
    @Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        g.drawImage(img, 1, 1, null);
    }

    private boolean inRange(int from, int to, int x) {
        return (x >= from && x <= to);
    }

    private boolean contains(Point pLT, Point pRB, Point eLT, Point eRB) {
        return (inRange(pLT.x, pRB.x, eLT.x)
                || inRange(pLT.x, pRB.x, eRB.x))
                && (inRange(pLT.y, pRB.y, eLT.y)
                || inRange(pLT.y, pRB.y, eRB.y));
    }

    /**
     * Check if position (x,y) is on displayed part of containing panel - if true, display entity
     */
    public void updateLocation() {
        Point offset = MapRenderer.getMapOffset();
        
        // calculate equivalent of (0,0) on whole panel
        int offsetX = offset.x * Config.tileWidth;
        int offsetY = offset.y * Config.tileHeight;

        Point entityLT = new Point(this.x, this.y);
        Point entityRB = new Point(this.x + getWidth(), this.y + getHeight());

        Point panelLT = new Point(offsetX, offsetY);
        Point panelRB = new Point(offsetX + panelContaining.getWidth(), offsetY
                + panelContaining.getHeight());

        if (contains(panelLT, panelRB, entityLT, entityRB)) {
            setLocation(this.x - offsetX, this.y - offsetY);
            addToProperPanel();
        } else {
            removeFromProperPanel();
        }

    }

    /**
     * Adds entity to proper panel
     */
    protected void addToProperPanel() {
        if (!visable) {
            panelContaining.add(this);
            panelContaining.repaint();
        }

        visable = true;
    }

    /**
     * Removes entity from proper panel
     */
    protected void removeFromProperPanel() {
        if (visable) {
            panelContaining.remove(this);
            panelContaining.repaint();
        }

        visable = false;
    }
    
    /**
     * Updates properties of entity
     */
    protected synchronized void updateProperties(){
        properties.put("x", Integer.toString(this.x));
        properties.put("y", Integer.toString(this.y));
        properties.put("myName", myName);
    }
    
    /**
     * returns key-value properties of entity
     * @return key-value properties
     */
    public HashMap<String, String> getProperties(){
        return properties;
    }
}
